<script setup lang="ts">
import { Form, Modal } from 'ant-design-vue';
import type { CurrencyBalance, FuKuanFangShiXiangQing } from '~/api/services/main.api';
import { jsBridge } from '~/utils/defines';
import LastTransaction from '../Comps/LastTransaction.vue';
import { useActivityWelcomeBonus, usePwaBonusInfo, useSignUpBonusInfo, useWelcomeBonusInfo } from '../ts/depositBonusInfoHook';
import { addSecond, filterInputNum, openUrl, toBnInt, toBnVal, toDecimalPlaces, toRateText } from '../ts/utils';
import Bonus, { type BonusKeyType } from './Bonus.vue';
import { fiatResultPopup } from './FiatResult.vue';

const props = defineProps<{
  currencyInfo?: CurrencyBalance;
  method?: FuKuanFangShiXiangQing;
  isLoadingMethod: boolean;
  readyData?: Api.GetData<typeof apis.apiFundDepositReadyAll>;
  checkedBonusKey?: BonusKeyType;
}>();

const { refetchActivity } = useActivityWelcomeBonus();

const formData = reactive({
  bank_code: undefined as unknown as string,
  amount: '',
  bank_card_name: '',
  phone: '',
  cpf: '',
  email: '',
  bank_card_no: '',
});

const getCurrencyRef = computed(() => props.currencyInfo?.currency ?? '');

const { getExtraAmountRef, findDetailToAmount } = useWelcomeBonusInfo(getCurrencyRef, computed(() => formData.amount));

const { getSignUpBonusDataRef } = useSignUpBonusInfo(false, getCurrencyRef);

const { getPwaBonusDataRef } = usePwaBonusInfo(false, getCurrencyRef);

const welcomeBonusLen = ref(0);
const bonusKeyRef = ref<BonusKeyType | undefined>(props.checkedBonusKey);

watch([bonusKeyRef, welcomeBonusLen, getSignUpBonusDataRef], ([key, len, _data]) => {
  const val = toBnInt(_data?.bnDepositAmount || bignumber(0));
  if (key === 'signUp' && len > 0 && val.gt(0)) {
    formData.amount = val.toString();
  }
}, { immediate: true });

const getBnExtraAmountRef = computed(() => {
  if (bonusKeyRef.value === 'welcome') {
    return welcomeBonusLen.value > 0 ? getExtraAmountRef.value : bignumber(0);
  }
  const bnInputVal = toBnVal(formData.amount);
  if (bonusKeyRef.value === 'signUp') {
    const data = getSignUpBonusDataRef.value;
    const _minDeposit = toBnInt(data?.bnDepositAmount || bignumber(0));
    if (!data || !bnInputVal || _minDeposit.lte(0) || bnInputVal.lt(_minDeposit)) {
      return bignumber(0);
    }
    return toBnInt(data.bnAmount);
  }
  const pwaVal = toBnVal(getPwaBonusDataRef.value?.bnAmount);
  if (bonusKeyRef.value === 'pwa' && bnInputVal && pwaVal) {
    return toBnInt(pwaVal);
  }
  return bignumber(0);
});

const getBankCodeOptionsRef = computed(() => {
  const list = props.method?.banks || [];
  return list.map(x => ({ label: x.bank_name, value: x.bank_code, is_default: x.is_default }));
});

watch(getBankCodeOptionsRef, (v) => {
  if (v.length) {
    const def = v.find(x => x.is_default) || v[0];
    formData.bank_code = def?.value ?? '';
  }
}, { immediate: true });

function filterBankCodeOption(input: string, option: any) {
  return option?.value?.toLowerCase?.().includes(input?.toLowerCase?.()) || option?.label?.toLowerCase?.().includes(input?.toLowerCase?.());
}

const getIsNameRef = computed(() => !!props.method?.is_name);

const getIsPhoneRef = computed(() => !!props.method?.is_phone);

const getIsCpfRef = computed(() => !!props.method?.is_cpf);

const getIsEmailRef = computed(() => !!props.method?.is_email);

const getCardNoRef = computed(() => !!props.method?.is_card_no);

const getServiceRateRef = computed(() => {
  const rate = toBnVal(props.method?.fee);
  const bnRate = rate?.gt(0) ? rate : bignumber(0);
  const type = props.method?.fee_type;
  return {
    type,
    bnRate,
    text: bnRate.gt(0) && type === 2 ? toRateText(bnRate, false) : '',
  };
});

const getServiceAmountRef = computed(() => {
  const { type, bnRate } = getServiceRateRef.value;
  if (bnRate.gt(0)) {
    const inputVal = toBnVal(formData.amount);
    if (inputVal?.gt(0) && type === 2) {
      return toDecimalPlaces(inputVal.multipliedBy(bnRate));
    }
    return toDecimalPlaces(bnRate);
  }
  return bignumber(0);
});

const getReceivedAmountRef = computed(() => {
  const inputVal = toBnVal(formData.amount);
  if (!inputVal?.gt(0)) {
    return bignumber(0);
  }
  const result = toDecimalPlaces(inputVal.minus(getServiceAmountRef.value));
  return result.gt(0) ? result : bignumber(0);
});

const getMinMaxRef = computed(() => {
  const bnMin = toBnVal(props.method?.min_deposit_amount);
  const _min = bnMin ? toDecimalPlaces(bnMin, false, bnMin.decimalPlaces() ?? 2) : bignumber(0);
  const resMin = getServiceRateRef.value.type === 2 ? _min : bignumber.max(getServiceAmountRef.value, _min);
  const bnMax = toBnVal(props.method?.max_deposit_amount);
  const resMax = bnMax ? toDecimalPlaces(bnMax, false, bnMax.decimalPlaces() ?? 2) : bignumber(0);
  return { min: resMin, max: resMax };
});

const getMinMaxPlaceholder = computed(() => {
  const { min, max } = getMinMaxRef.value;
  if (min.lte(0) || max.lte(0)) {
    return '';
  }
  return ` (${min.toFormat()} ~ ${max.toFormat()})`;
});

const $form = Form.useForm(formData, reactive({
  amount: [
    {
      validator(_: any, val: string) {
        const inputVal = toBnVal(val);

        if (!inputVal || inputVal?.lte(0))
          return formResult($t('w01vGQpDtd5FuknyBeCfN'));

        if (!inputVal.isInteger())
          return formResult($t('5Jzfj3NvqPzFh04Mu8qmR'));

        const { min, max } = getMinMaxRef.value;

        if (max.gt(0) && inputVal.gt(max))
          return formResult($t('qC6v6d42euZdM70uSgZb', { amount: max.toFormat() }));

        if (min.gt(0) && inputVal.lt(min))
          return formResult($t('6GaQiG5cpy5b6o2c_3VzZ', { amount: min.toFormat() }));

        return formResult();
      },
    },
  ],
  bank_code: [
    {
      validator(_: any, value: string) {
        if (getBankCodeOptionsRef.value.length > 0 && !value)
          return formResult($t('5UlRpoHeehGPj17ntpLg'));

        return formResult();
      },
    },
  ],
  bank_card_name: [
    {
      validator(_: any, value: string) {
        if (getIsNameRef.value && !value)
          return formResult($t('sofSLy2W5gtkQLou4yoLn'));

        return formResult();
      },
    },
  ],
  phone: [
    {
      validator(_: any, value: string) {
        if (getIsPhoneRef.value && !value)
          return formResult($t('gwOfiSWaNljicDlBydtH8'));

        return formResult();
      },
    },
  ],
  cpf: [
    {
      validator(_: any, value: string) {
        if (getIsCpfRef.value && !value)
          return formResult($t('tM7YMhZnMxeD6ArO57q'));

        return formResult();
      },
    },
  ],
  email: [
    {
      validator(_: any, value: string) {
        if (getIsEmailRef.value && !value)
          return formResult($t('aw95tLwTkGmrgSVCHW'));
        return formResult();
      },
    },
  ],
  bank_card_no: [
    {
      validator(_: any, value: string) {
        if (getCardNoRef.value && !value)
          return formResult($t('wSLcpiV6qaPprBe642tf'));
        return formResult();
      },
    },
  ],
}));

watch(getCurrencyRef, (v) => {
  if (v) {
    formData.amount = '';
    setTimeout(() => $form.clearValidate());
  }
});

const getAmountItemsRef = computed(() => {
  return [...new Set((props.method?.quick_options || []))].map((x) => {
    const bnX = toBnVal(x);
    if (x !== '' && bnX) {
      const { min: bnMin, max: bnMax } = getMinMaxRef.value;
      if ((bnMin.gt(0) && bnMin.gt(bnX)) || (bnMax.gt(0) && bnX.gt(bnMax))) {
        return false;
      }
      return {
        rateText: findDetailToAmount(bnX)?.rateText ?? '',
        value: bnX.toString(),
        label: (`${props.currencyInfo?.symbol ?? ''} ${bnX.toFormat()}`).trim(),
      };
    }
    return false;
  }).filter(a => !!a);
});

function getAmountItemsCls(val: string) {
  const isActive = formData.amount && val === formData.amount && bonusKeyRef.value === 'welcome';
  return { '!bg-sys-layer-e': isActive };
}

const bonusDomRef = ref();

function selectAmountItem(item: typeof getAmountItemsRef.value[0]) {
  const bnVal = toBnInt(bignumber(item.value));
  if (bnVal.isNaN() || bnVal.lte(0)) {
    formData.amount = '0';
  }
  else {
    formData.amount = bnVal.toString();
    item.rateText && bonusDomRef.value?.setRadio?.('welcome');
  }
}

async function inputAmount(e: any) {
  await nextTick();
  formData.amount = filterInputNum(e.target?.value, 'int', 0);
}

const checkValue = ref(true);

function openResultPopup(
  res: Api.GetData<typeof apis.apiFundDepositSubmit>,
  body: Api.GetParam<typeof apis.apiFundDepositSubmit>['requestBody'],
) {
  fiatResultPopup.open({
    method: props.method,
    currency: getCurrencyRef.value,
    amount: toBnInt(bignumber(body?.amount || formData.amount)).toFormat(),
    orderNo: res.order_no,
    createTime: res.create_time,
    expireDate: addSecond(res.expire_second),
    onContinue: () => openUrl(res.data),
  });
  if (envs.isMobile && envs.isIos) {
    const m = Modal.confirm({
      title: null,
      content: () => h('div', { class: 'w-full text-center text-base' }, $t('cdxl5Yb4HoQoEb3KakP33')),
      centered: true,
      width: 300,
      zIndex: 999999,
      icon: null,
      closable: false,
      okText: $t('rsne1ItM761zjJqm3Dj5'),
      class: 'confirm-box-scoped',
      cancelButtonProps: { class: 'cancel-btn', size: 'small' } as Record<string, any>,
      okButtonProps: { class: 'ok-btn', size: 'small' } as Record<string, any>,
      onOk: () => openUrl(res.data),
      onCancel() {
        m?.destroy?.();
      },
    });
  }
  else {
    openUrl(res.data);
  }
}

const depositMut = useMutation({
  mutationKey: [apis.apiFundDepositSubmit.id],
  mutationFn: apis.apiFundDepositSubmit.setDefaultConfig({ successMessage: false, errorMessage: true }),
  onSuccess(res, { requestBody: body }) {
    refetchActivity();
    res.type === 'url' && openResultPopup(res, body);
    $form.resetFields();
    $form.clearValidate();
  },
});

const btnLoading = computed(() => depositMut.isPending.value);

async function handleSubmit() {
  if (!(await $form.validate().catch(() => false)) || !props.method)
    return;

  if (!checkValue.value) {
    antdMessage.error({ content: $t('uVTbey9dnjH8JxkaJqycC'), duration: 3 });
    return;
  }

  jsBridge.post('rechargeClick', { isFiat: 1, currency: getCurrencyRef.value, amount: formData.amount });
  depositMut.mutate({
    requestBody: {
      currency: getCurrencyRef.value,
      code: props.method?.code ?? '',
      bank_code: (getBankCodeOptionsRef.value.length ? formData.bank_code : props.method?.bank_code) ?? '',
      amount: toBnInt(bignumber(formData.amount)).toNumber(),
      bank_card_name: getIsNameRef.value ? formData.bank_card_name : void 0,
      phone: getIsPhoneRef.value ? formData.phone : void 0,
      cpf: getIsCpfRef.value ? formData.cpf : '',
      email: getIsEmailRef.value ? formData.email : void 0,
      bank_card_no: getCardNoRef.value ? formData.bank_card_no : '',
    },
  });
}
</script>

<template>
  <div class="relative flex flex-1 flex-col justify-between text-sm text-sys-text-body lt-mobile:h-full">
    <div class="lt-mobile:(flex flex-1 flex-col overflow-y-auto)">
      <AForm @keypress.enter="handleSubmit">
        <AFormItem class="!mb-3">
          <slot />
        </AFormItem>

        <div v-if="!!method">
          <AFormItem v-if="getIsNameRef && !isLoadingMethod" v-bind="$form.validateInfos.bank_card_name" class="!mb-3">
            <div class="mb-1.5 text-sm text-sys-text-body">
              {{ $t('rfIbEfnX97O_1stKmtlLh') }}
            </div>
            <AInput
              v-model:value="formData.bank_card_name"
              allowClear
              :placeholder="$t('sofSLy2W5gtkQLou4yoLn')"
            />
          </AFormItem>

          <AFormItem v-if="getBankCodeOptionsRef.length && !isLoadingMethod" v-bind="$form.validateInfos.bank_code" class="!mb-3">
            <div class="mb-1.5 text-sm text-sys-text-body">
              {{ $t('n04tTDh_3bQxof7jzqVb') }}
            </div>
            <ASelect
              v-model:value="formData.bank_code"
              :placeholder="$t('5UlRpoHeehGPj17ntpLg')"
              :dropdownMatchSelectWidth="false"
              :listHeight="300"
              :options="getBankCodeOptionsRef"
              showSearch
              :filterOption="filterBankCodeOption"
              @change="$form.clearValidate()"
            >
              <template #option="{ label }">
                <div class="max-w-90 truncate lt-mobile:max-w-[86vw]">
                  {{ label }}
                </div>
              </template>
            </ASelect>
          </AFormItem>

          <AFormItem v-if="getCardNoRef" v-bind="$form.validateInfos.bank_card_no" class="!mb-3">
            <div class="mb-1.5 text-sm text-sys-text-body">
              {{ $t('gfCIm5hYXujRb9IlRckR') }}
            </div>
            <AInput
              v-model:value="formData.bank_card_no"
              allowClear
              :placeholder="$t('nHztsuT0oVSzMbpIgCn3')"
            />
          </AFormItem>

          <AFormItem v-if="getIsEmailRef" v-bind="$form.validateInfos.email" class="!mb-3">
            <div class="mb-1.5 text-sm text-sys-text-body">
              {{ $t('wxnfCdf43thnacVZgQa1') }}
            </div>
            <AInput
              v-model:value="formData.email"
              allowClear
              :placeholder="$t('hVaEobWzd70kjGP9Awnt')"
            />
          </AFormItem>

          <AFormItem v-if="getIsPhoneRef" v-bind="$form.validateInfos.phone" class="!mb-3">
            <div class="mb-1.5 text-sm text-sys-text-body">
              {{ $t('qOwMMelgnPiNGweE3jNYl') }}
            </div>
            <AInput
              v-model:value="formData.phone"
              allowClear
              :placeholder="$t('gwOfiSWaNljicDlBydtH8')"
            />
          </AFormItem>

          <AFormItem v-if="getIsCpfRef" v-bind="$form.validateInfos.cpf" class="!mb-3">
            <div class="mb-1.5 text-sm text-sys-text-body">
              Cpf
            </div>
            <AInput
              v-model:value="formData.cpf"
              allowClear
              :placeholder="$t('tM7YMhZnMxeD6ArO57q')"
            />
          </AFormItem>

          <AFormItem v-bind="$form.validateInfos.amount" class="!mb-3">
            <div class="mb-1.5 text-sm text-sys-text-body">
              {{ $t('gISik9oabNrFv20d9znt') }}{{ getMinMaxPlaceholder }}
            </div>
            <AInput
              v-model:value="formData.amount"
              allowClear
              :placeholder="`${$t('qlxJcfsbDcKdovNZpjeKl')}${getMinMaxPlaceholder}`"
              inputmode="numeric"
              :maxlength="18"
              :prefix="currencyInfo?.symbol"
              @change="inputAmount"
              @blur="inputAmount"
            >
              <template v-if="getBnExtraAmountRef.gt(0)" #suffix>
                <div class="flex items-center gap-0.5 whitespace-normal break-words break-all text-xs text-yellow-500">
                  <span>{{ $t('cQEwyovhdz7kiAaCheaE') }}</span>
                  <span>{{ currencyInfo?.symbol }}</span>
                  <span>{{ getBnExtraAmountRef.toFormat() }}</span>
                </div>
              </template>
            </AInput>
          </AFormItem>
          <AFormItem v-if="isLoadingMethod" class="!mb-0" :class="{ '!mb-3': !getAmountItemsRef.length }">
            <TSkeleton class="grid grid-cols-3 mb-3 mt-2 gap-2">
              <TSkeleton type="rect" width="auto" height="36px" />
              <TSkeleton type="rect" width="auto" height="36px" />
              <TSkeleton type="rect" width="auto" height="36px" />
            </TSkeleton>
          </AFormItem>
          <AFormItem v-else-if="getAmountItemsRef.length" class="!mb-0">
            <div class="grid grid-cols-3 mb-3 mt-2 gap-2">
              <div
                v-for="(item, idx) of getAmountItemsRef"
                :key="idx"
                class="relative max-w-full w-full cursor-pointer truncate rounded-lg bg-sys-layer-d px-1.5 py-3 text-center text-[13px] text-sys-text-head"
                :class="getAmountItemsCls(item.value)"
                @click="selectAmountItem(item)"
              >
                {{ item.label }}
                <div v-if="item.rateText" class="absolute right-0 top-0 h-3 max-w-full flex items-center justify-center truncate rounded-bl-lg rounded-tr-lg bg-green-500 px-[3px] text-2.5 text-sys-text-head font-bold">
                  +{{ item.rateText }}
                </div>
              </div>
            </div>
          </AFormItem>

          <div class="grid grid-cols-1 gap-2">
            <AFormItem class="!mb-0">
              <Bonus
                ref="bonusDomRef"
                v-model:welcomeBonusLen="welcomeBonusLen"
                v-model:bonusKey="bonusKeyRef"
                :currency="getCurrencyRef"
                hieednBottomLine
                isFiat
                :bnMin="getMinMaxRef.min"
                :bnMax="getMinMaxRef.max"
                :checkedBonusKey="checkedBonusKey"
              />
            </AFormItem>

            <AFormItem v-if="getServiceAmountRef.gt(0) && getReceivedAmountRef.gt(0)" class="!mb-3">
              <div>{{ $t('np4skhNFeYpCk9AepQq') }}</div>
              <div class="grid grid-cols-[auto_1fr] mb-3 mt-1.5 items-center gap-x-2 border-(1px sys-layer-e solid) rounded-lg bg-sys-layer-d px-2.5 py-1.5">
                <div class="text-xs">
                  {{ $t('txnBsvvLm0IcSoZ0lYusm') }}
                </div>
                <div class="whitespace-normal break-words break-all text-right text-xl text-green font-semibold">
                  {{ getReceivedAmountRef.toFormat() }}
                </div>
                <div class="text-xs">
                  {{ $t('mnzMeff8rTooSapjfgwIr') }} {{ getServiceRateRef.text }}
                </div>
                <div class="whitespace-normal break-words break-all text-right">
                  {{ `${getServiceAmountRef.toFormat()} ${getCurrencyRef}`.trim() }}
                </div>
              </div>
            </AFormItem>
          </div>
        </div>
      </AForm>
      <LastTransaction :class="{ '!hidden': !method }" />
    </div>

    <div v-if="!!method" class="lt-mobile:(mb-3 mt-auto)">
      <AButton
        class="ant-cover__Button-3d-primary w-full !my-3"
        type="primary"
        :loading="btnLoading"
        :disabled="btnLoading"
        @click="handleSubmit"
      >
        {{ $t('p9zKloGqNTkIgC4asiQrx') }}
      </AButton>

      <div class="mt-3 flex items-start gap-1.5">
        <ACheckbox v-model:checked="checkValue" />
        <div class="flex-1">
          <span class="mr-1.5 cursor-pointer text-sys-text-body" @click="checkValue = !checkValue">
            {{ $t('0bbyzrPk4eYccGuD64tB') }}
          </span>
          <ATooltip class="van-cover__popver" placement="topRight" :offset="[-10, 8]" :title="$t('lzse921CgOu9oSzr9loqu')">
            <i class="i-ri:question-line inline-block h-4 w-4 text-4 text-sys-text-body" />
          </ATooltip>
        </div>
      </div>
    </div>
    <fiatResultPopup.PresetComponent />
  </div>
</template>

<style lang="scss">
.confirm-box-scoped .ant-modal-body {
  .ant-modal-confirm-content {
    --uno: '!w-full !max-w-full';
  }

  .ant-modal-confirm-btns {
    --uno: '!mt-7.5 !text-center';

    .cancel-btn {
      --uno: 'min-w-20 !text-[13px] !bg-[#3E404C] !border-[#3E404C] !rounded-full !font-medium';
    }
    .ok-btn {
      --uno: '!ml-7.5 min-w-20 !text-[13px] !bg-primary !border-primary !rounded-full !font-medium';
    }
  }
}
</style>
